package com.itjin.health.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ObjectMetadata;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itjin.health.domain.dto.QrCodeRequest;
import com.itjin.health.domain.entity.GroupChatQrCode;
import com.itjin.health.domain.entity.User;
import com.itjin.health.domain.vo.QrCodeVO;
import com.itjin.health.exception.BusinessException;
import com.itjin.health.exception.ErrorCode;
import com.itjin.health.mapper.GroupChatQrCodeMapper;
import com.itjin.health.mapper.UserMapper;
import com.itjin.health.service.GroupChatQrCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class GroupChatQrCodeServiceImpl extends ServiceImpl<GroupChatQrCodeMapper, GroupChatQrCode>
    implements GroupChatQrCodeService {

  @Resource
  private OSS ossClient;

  @Resource
  private UserMapper userMapper;

  @Value("${alibaba.cloud.oss.bucket-name}")
  private String bucketName;

  @Value("${alibaba.cloud.oss.endpoint}")
  private String endpoint;

  @Override
  public GroupChatQrCode uploadQrCode(MultipartFile qrCodeImage, String expiryTime, String status, Integer userId) {
    // 验证用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
    }

    // 验证用户权限
    if (!"管理员".equals(user.getRole()) && !"教师".equals(user.getRole()) && !"超级管理员".equals(user.getRole())) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "只有管理员、教师和超级管理员可以上传二维码");
    }

    // 验证文件
    if (qrCodeImage == null || qrCodeImage.isEmpty()) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "请选择二维码图片");
    }

    // 文件类型验证
    String contentType = qrCodeImage.getContentType();
    if (contentType == null || !contentType.startsWith("image/")) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "只支持上传图片文件");
    }

    // 解析过期时间
    LocalDateTime expiry = null;
    if (expiryTime != null && !expiryTime.isEmpty()) {
      try {
        expiry = LocalDateTime.parse(expiryTime, DateTimeFormatter.ISO_DATE_TIME);
      } catch (DateTimeParseException e) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "过期时间格式不正确，请使用ISO格式");
      }
    }

    try {
      // 生成文件名
      String originalFilename = qrCodeImage.getOriginalFilename();
      String suffix = "";
      if (originalFilename != null && originalFilename.contains(".")) {
        suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
      }
      String fileName = "qrcode/" + UUID.randomUUID() + suffix;

      // 设置OSS元数据
      ObjectMetadata metadata = new ObjectMetadata();
      metadata.setContentType(contentType);
      metadata.setContentLength(qrCodeImage.getSize());

      // 上传到OSS
      ossClient.putObject(bucketName, fileName, qrCodeImage.getInputStream(), metadata);

      // 生成访问URL
      String qrCodeUrl = "https://" + bucketName + "." + endpoint + "/" + fileName;

      // 创建二维码记录
      GroupChatQrCode qrCode = new GroupChatQrCode();
      qrCode.setQrCodeUrl(qrCodeUrl);
      qrCode.setUploadTime(LocalDateTime.now());
      qrCode.setExpiryTime(expiry);
      qrCode.setStatus(status != null && !status.isEmpty() ? status : "Active");
      qrCode.setCreatedBy(userId);

      // 保存到数据库
      boolean result = this.save(qrCode);
      if (!result) {
        throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传二维码失败，数据库错误");
      }

      return qrCode;
    } catch (IOException e) {
      log.error("上传二维码失败", e);
      throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传二维码失败：" + e.getMessage());
    }
  }

  @Override
  public boolean updateQrCode(QrCodeRequest qrCodeRequest, Integer userId) {
    if (qrCodeRequest == null || qrCodeRequest.getQrCodeId() == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
    }

    // 验证用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
    }

    // 验证用户权限
    if (!"管理员".equals(user.getRole()) && !"教师".equals(user.getRole()) && !"超级管理员".equals(user.getRole())) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "只有管理员、教师和超级管理员可以修改二维码");
    }

    // 获取二维码记录
    GroupChatQrCode qrCode = this.getById(qrCodeRequest.getQrCodeId());
    if (qrCode == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "二维码不存在");
    }

    // 如果提供了新图片，则更新图片
    if (qrCodeRequest.getQrCodeImage() != null && !qrCodeRequest.getQrCodeImage().isEmpty()) {
      MultipartFile qrCodeImage = qrCodeRequest.getQrCodeImage();

      // 文件类型验证
      String contentType = qrCodeImage.getContentType();
      if (contentType == null || !contentType.startsWith("image/")) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "只支持上传图片文件");
      }

      try {
        // 生成文件名
        String originalFilename = qrCodeImage.getOriginalFilename();
        String suffix = "";
        if (originalFilename != null && originalFilename.contains(".")) {
          suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        String fileName = "qrcode/" + UUID.randomUUID() + suffix;

        // 设置OSS元数据
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(contentType);
        metadata.setContentLength(qrCodeImage.getSize());

        // 上传到OSS
        ossClient.putObject(bucketName, fileName, qrCodeImage.getInputStream(), metadata);

        // 生成访问URL
        String qrCodeUrl = "https://" + bucketName + "." + endpoint + "/" + fileName;

        // 更新URL
        qrCode.setQrCodeUrl(qrCodeUrl);
      } catch (IOException e) {
        log.error("更新二维码图片失败", e);
        throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新二维码图片失败：" + e.getMessage());
      }
    }

    // 更新其他信息
    if (qrCodeRequest.getQrCodeUrl() != null && !qrCodeRequest.getQrCodeUrl().isEmpty()) {
      qrCode.setQrCodeUrl(qrCodeRequest.getQrCodeUrl());
    }
    if (qrCodeRequest.getExpiryTime() != null) {
      qrCode.setExpiryTime(qrCodeRequest.getExpiryTime());
    }
    if (qrCodeRequest.getStatus() != null && !qrCodeRequest.getStatus().isEmpty()) {
      qrCode.setStatus(qrCodeRequest.getStatus());
    }

    // 记录更新人
    qrCode.setUpdatedBy(userId);

    // 保存到数据库
    return this.updateById(qrCode);
  }

  @Override
  public boolean deleteQrCode(Integer qrCodeId, Integer userId) {
    if (qrCodeId == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
    }

    // 验证用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
    }

    // 验证用户权限
    if (!"管理员".equals(user.getRole()) && !"教师".equals(user.getRole()) && !"超级管理员".equals(user.getRole())) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "只有管理员、教师和超级管理员可以删除二维码");
    }

    // 获取二维码记录
    GroupChatQrCode qrCode = this.getById(qrCodeId);
    if (qrCode == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "二维码不存在");
    }

    // 从数据库中删除
    return this.removeById(qrCodeId);
  }

  @Override
  public GroupChatQrCode getQrCode(Integer qrCodeId) {
    if (qrCodeId == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
    }

    // 获取二维码记录
    GroupChatQrCode qrCode = this.getById(qrCodeId);
    if (qrCode == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "二维码不存在");
    }

    return qrCode;
  }

  @Override
  public Page<GroupChatQrCode> listQrCodes(long current, long size, String status) {
    // 创建分页对象
    Page<GroupChatQrCode> page = new Page<>(current, size);

    // 构建查询条件
    QueryWrapper<GroupChatQrCode> queryWrapper = new QueryWrapper<>();

    // 状态筛选
    if (status != null && !status.isEmpty()) {
      queryWrapper.eq("status", status);
    }

    // 按上传时间降序排序
    queryWrapper.orderByDesc("upload_time");

    // 执行分页查询
    return this.page(page, queryWrapper);
  }

  @Override
  public GroupChatQrCode getLatestActiveQrCode() {
    // 构建查询条件
    QueryWrapper<GroupChatQrCode> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("status", "Active");

    // 当前时间
    LocalDateTime now = LocalDateTime.now();

    // 查询未过期或没有设置过期时间的二维码
    queryWrapper.and(wrapper -> wrapper.isNull("expiry_time").or().gt("expiry_time", now));

    // 按上传时间降序排序，获取最新的
    queryWrapper.orderByDesc("upload_time");

    // 执行查询
    return this.getOne(queryWrapper);
  }

  /**
   * 将二维码实体转换为视图对象
   *
   * @param qrCode 二维码实体
   * @return 二维码视图对象
   */
  public QrCodeVO getQrCodeVO(GroupChatQrCode qrCode) {
    if (qrCode == null) {
      return null;
    }

    QrCodeVO qrCodeVO = new QrCodeVO();
    BeanUtils.copyProperties(qrCode, qrCodeVO);

    // 获取创建者和更新者的用户名
    if (qrCode.getCreatedBy() != null) {
      User creator = userMapper.selectById(qrCode.getCreatedBy());
      if (creator != null) {
        qrCodeVO.setCreatorName(creator.getUsername());
      }
    }

    if (qrCode.getUpdatedBy() != null) {
      User updater = userMapper.selectById(qrCode.getUpdatedBy());
      if (updater != null) {
        qrCodeVO.setUpdaterName(updater.getUsername());
      }
    }

    return qrCodeVO;
  }

  /**
   * 将二维码实体列表转换为视图对象列表
   *
   * @param qrCodes 二维码实体列表
   * @return 二维码视图对象列表
   */
  public List<QrCodeVO> getQrCodeVOList(List<GroupChatQrCode> qrCodes) {
    if (qrCodes == null || qrCodes.isEmpty()) {
      return new ArrayList<>();
    }

    List<QrCodeVO> qrCodeVOList = new ArrayList<>();
    for (GroupChatQrCode qrCode : qrCodes) {
      qrCodeVOList.add(getQrCodeVO(qrCode));
    }

    return qrCodeVOList;
  }
}